module executor.initialization.client.InitExecutor;

import msgtrans;
import message.Constants;
import cache.UserStatusManager;
import hunt.logging;
import google.protobuf;
import message.MsgDefine;
import cache.ChatIdMap;
import client.GateServerClient;
import client.MsgServerClient;
import std.array;
import std.conv : to;
import std.stdio;
import client.LogicServerClient;

/**
 * 启动时的初始化操作
 * 
 * 初始化ChatIdMap和UserStatusManager
 * 
 */
@TransportClient(LogicClientName)
class InitExecutor : AbstractExecutor!(InitExecutor)
{
    @MessageId(MESSAGE.CMD_CHATMAP)
    void initChatMap(TransportContext ctx, MessageBuffer buffer) //初始化动作，当连接上logicServer之后 logice会推送chatId关系列表给msgserver
    {
        ChatMap mp = new ChatMap;
        buffer.data.fromProtobuf!ChatMap(mp);
        foreach(GroupInfo member; mp.map)
        {
            int chatId = member.groupId;
            string[string] users;
            foreach(int userId ; member.memberId)
            {
                users[to!string(userId)] = to!string(userId);
            }
            ChatIdMap.getInstance().createChat(to!string(chatId),users);
            logInfo("initChatMap ----- %s",    chatId);
            std.stdio.stdout.flush();
        }

        foreach(int id ; mp.onlineMember)
        {
            //UserStatusManager.getInstance().setUserStatus(to!string(id),true);
        }

    }

     @MessageId(MESSAGE.CMD_SET_GROUP_NAME_REQ)
     void setName(TransportContext ctx, MessageBuffer buffer)
     {
         SetGroupNameREQ req = new SetGroupNameREQ;
         buffer.data.fromProtobuf!SetGroupNameREQ( req);
         string[string] chatMap = ChatIdMap.getInstance().getGroupInfo( req.groupId);

         auto res = new SetGroupNameRES;
         res.groupId = req.groupId;
         res.groupName = req.groupName;
         res.succeeded = true;

         foreach (string clientId ; chatMap)
         {
             res.userId = clientId;

             MessageTransportClient client = MsgServerClient.getInstance.getForwardClient(clientId);
             if (client is null) //hash到本机
             {
                 logInfo( "clientId local: %s",clientId);
                 if (UserStatusManager.getInstance().getUserStatus(clientId))
                 {
                     TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
                     foreach (TransportSession c ; contexts)
                     {
                         c.send( new MessageBuffer( MESSAGE.CMD_SET_GROUP_NAME_RES,res.toProtobuf.array));
                     }
                 }
             }else
             {
                 logInfo( "clientId other server: %s",clientId);
                 client.send( new MessageBuffer(MESSAGE.CMD_SET_GROUP_NAME_HASH_RES,res.toProtobuf.array));
             }
         }
     }

    @MessageId(MESSAGE.CMD_CHAT_MAP_ACTION)
    void chatMapAction(TransportContext ctx, MessageBuffer buffer) //chatId关系列表同步接口
    {
        ChatMapAction action = new ChatMapAction;
        buffer.data.fromProtobuf!ChatMapAction(action);
        string[string] strMember;
        switch (action.type)
        {
            case ChatMapActionType.CREATE: //新创建
            {
                string[string] users;
                foreach(string m ; action.member)
                {
                    users[m] = m;
                }
                ChatIdMap.getInstance().createChat(action.chatId, users);
                updateGroupList(action.chatId,users,action);
                break;
            }
            case ChatMapActionType.ADD: //添加
            {
                foreach(string m ; action.member)
                {
                    ChatIdMap.getInstance().addMember(action.chatId, m);
                    strMember[m] = m;
                }
                updateGroupList(action.chatId, strMember, action);
                break;
            }
            case ChatMapActionType.KICK: //踢出
                    goto case;
            case ChatMapActionType.DELETE: //删除
            {

                foreach(string m ; action.member)
                {
                    ChatIdMap.getInstance().deleMember(action.chatId, m);
                    strMember[m] = m;
                }
                updateGroupList(action.chatId, strMember, action);
                break;
            }
            case ChatMapActionType.DESTROY:
            {
                ChatIdMap.getInstance().deleChat(action.chatId);
                // updateGroupList(action.chatId, strMember, action);
                break;
            }
            default:
                break;
        }

        logInfof("chatMapAction ----- %d ----%s", action.type, action.chatId);
    }
}

void updateGroupList(string chatId, string[string] newMember , ChatMapAction action)
{
    string[string] chatMap =    ChatIdMap.getInstance().getGroupInfo(chatId);
    if(chatMap.length == 0)
    {
            ChatIdMap.getInstance().deleChat(chatId);
    }
    foreach(string clientId ; chatMap)
    {
        //if (clientId in newMember)
        //{
        //    continue;
        //}
        action.destination = clientId;

        MessageTransportClient client = MsgServerClient.getInstance.getForwardClient(clientId);
        if (client is null) //hash到本机
        {
            logInfo("clientId local: %s",clientId );
            if (UserStatusManager.getInstance().getUserStatus(clientId))
            {
                TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
                foreach(TransportSession c ; contexts)
                {
                    logInfo("updateGroupList    %s    ----    %s ---- %d" ,    clientId , chatId , action.type);
                    c.send(new MessageBuffer(MESSAGE.CMD_GROUP_MEMBER_CHANGE, action.toProtobuf.array));
                }
            }
            else
            {
                if (action.type == ChatMapActionType.ADD || action.type == ChatMapActionType.CREATE)
                {
                    if(action.member.length == 1 && action.manager == action.member[0])
                    {
                            return;
                    }
                    MessageTransportClient logicClient = LogicServerClient.getInstance().getForwardClient();
                    string[] arr;

                    foreach (string m; action.member)
                    {
                            if(m != action.manager)
                            {
                                    arr ~= m;
                            }
                    }
                    //foreach(string m ; action.member)
                    //{
                    auto msg = new Msg;
                    msg.chatId = chatId;
                    msg.fromUserId = action.manager;
                    msg.message = arr.join(",");
                    msg.msgTime = action.timestamp;

                    if(action.type == ChatMapActionType.CREATE && action.member.length == 2)
                    {
                        msg.type = MsgType.NOTICE_CONTACTS_ADD;
                    }else
                    {
                        msg.type = MsgType.NOTICE_GROUP_ADD;
                    }

                    msg.localId = clientId;
                    logicClient.send(new MessageBuffer(MESSAGE.CMD_PUT_UNRECEIVE,msg.toProtobuf.array));
                    //}
                }
            }
        }
        else
        {
            logInfo("clientId other server: %s",clientId );
            client.send(new MessageBuffer(MESSAGE.CMD_GROUP_MEMBER_CHANGE_HASH,action.toProtobuf.array));
        }
    }
}
